我們在第五天的時候分享過工廠方法模式,今天的主題是它的進階版——抽象工廠模式。工廠方法模式每次只生成一種產品,而抽象工廠則用來生成整個產品家族。
在日本,許多電子賣場會在開學季推出促銷活動,將電風扇、冰箱以及電子鍋等中小型家電打包成套組,以較優惠的價格吸引顧客。假設每間廠商都推出自己的優惠組合,其中的內容物固定是電風扇、冰箱與電子鍋,如「松下優惠組合」或「索尼優惠組合」。這樣的概念就像抽象工廠一樣,這些優惠組合由同類型的產品組成,但來自不同的品牌,並由各自的工廠製造。
瀏覽網站時,你可能會注意到一些常見的視覺元素,例如按鈕、下拉選單和對話視窗等。這些元素通常遵循一定的行為模式,但它們的外觀往往會隨著網站的主題和視覺風格而有所不同。
假設我們要設計一個提示框元件,該元件不僅可以顯示提示訊息,還能讓使用者自訂提示框和按鈕的內容與樣式。我們可以定義一個提示框工廠,並將其作為提示框元件的初始化參數。這樣一來,使用者就能通過自訂義的提示框工廠來製作客製化元件。
首先,定義提示框工廠並將其設為提示框元件的初始化參數。
abstract class TooltipFactory<
Trigger extends Component,
Panel extends Component
> {
abstract createTrigger(): Trigger;
abstract createPanel(): Panel;
}
class Tooltip<Trigger extends Component, Panel extends Component> {
trigger: Trigger;
panel: Panel;
constructor(factory: TooltipFactory<Trigger, Panel>) {
this.trigger = factory.createTrigger();
this.panel = factory.createPanel();
}
render() {
this.trigger.render();
this.panel.render();
}
}
接著,定義兩個具體工廠,第一種工廠負責建立按鈕和提示文字,適用於基本的應用場景;第二種工廠則負責建立頭像與簡介,用來提供頭像的輔助說明。
class PlainTooltipFactory extends TooltipFactory<Button, SupportingText> {
createTrigger() {
return new Button();
}
createPanel() {
return new SupportingText();
}
}
class AvatarTooltipFactory extends TooltipFactory<Avatar, Profile> {
createTrigger() {
return new Avatar();
}
createPanel() {
return new Profile();
}
}
最後,測試提示框元件。
class TooltipTestDrive {
static main() {
const plainTooltipFactory = new PlainTooltipFactory();
const avatarTooltipFactory = new AvatarTooltipFactory();
const plainTooltip = new Tooltip(plainTooltipFactory);
const avatarTooltip = new Tooltip(avatarTooltipFactory);
plainTooltip.render();
avatarTooltip.render();
}
}
TooltipTestDrive.main();
這種設計的優點在於將外觀和內容的控制權完全交給使用者。使用者不僅能按照自己的喜好撰寫元素,還能根據需求進一步客製化元件內容。有了抽象工廠,我們可以透過不同的提示框工廠來製作各式各樣的提示框元件,滿足多樣化的需求。
抽象工廠包含兩種角色:
抽象工廠模式是一種創建型模式,它定義了一個產品家族的建立介面,讓具體工廠自訂每個產品的具體類別與生產細節。由於每個具體工廠都遵守相同的產品介面,客戶端只需依賴產品的介面而不需關心具體的產品類別,從而使客戶端與具體類別鬆綁。
這種模式允許使用者根據需求替換實體工廠,改變客戶端生產的具體產品,而不影響客戶端的程式邏輯。這種彈性的設計不僅提高了系統的可維護性,也增加了程式的可擴展性。